package com.wang.jmonkey.interceptor;

import cn.hutool.core.util.StrUtil;
import com.wang.jmonkey.common.constant.CacheConstant;
import com.wang.jmonkey.common.model.vo.UserVo;
import com.wang.jmonkey.common.utils.UserUtil;
import com.wang.jmonkey.interceptor.handler.result.ExceptionResultHandlerManager;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;

/**
 * @Description 装配登陆用户信息的拦截器
 * @Author HeJiawang
 * @Date 2021/5/20 14:36
 */
@Slf4j
public class LoginUserInterceptor implements MethodInterceptor {

    private RedisTemplate<String , Object> redis;

    private GenericApplicationContext context;

    public LoginUserInterceptor(RedisTemplate<String, Object> redis, GenericApplicationContext context) {
        this.redis = redis;
        this.context = context;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
            String username = UserUtil.Info.getUsername();

            UserVo userVo = redis.execute(new SessionCallback<>(){

                @Override
                public UserVo execute(RedisOperations operations) throws DataAccessException {
                    if (StrUtil.isNotEmpty(username) && operations.opsForHash().hasKey(CacheConstant.PermissionCache.USER_INFO.getKey(), username)) {
                        return (UserVo) operations.opsForHash().get(CacheConstant.PermissionCache.USER_INFO.getKey(), username);
                    }

                    return new UserVo();
                }
            });
            UserUtil.setUser(userVo);

            return invocation.proceed();
        } catch (Throwable e) {
            log.error(this.getClass().getName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName(), e);

            ExceptionResultHandlerManager manager = this.context.getBean(ExceptionResultHandlerManager.class);
            return manager.result(invocation.getMethod().getReturnType(), e.getMessage(), manager);
        } finally {

            UserUtil.clearUser();
        }
    }
}
